package com.zly.room.wsocket;

import com.alibaba.fastjson2.JSONObject;
import com.zly.room.entity.Message;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@ServerEndpoint("/ws/{token}") //
@Component
public class ChatServerEndpoint {
    //用线程安全的map来保存当前用户
    private static final Map<String, Session> onLineUsers = new ConcurrentHashMap<>();
    private static AtomicInteger onlineCount = new AtomicInteger(0);
    //声明一个session对象，通过该对象可以发送消息给指定用户，不能设置为静态，每个ChatEndPoint有一个session才能区分.(websocket的session)

    /**
     * websocket 打开连接时
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam("token") String token) {
        // token为连接的用户信息一般为jwt
        onLineUsers.put(token, session); // 把session 保存到
        log.info(token);
        int onlineUserCount = onlineCount.addAndGet(1);
        log.info("当前在线用户：{}", onlineUserCount);
        log.info("{}", session);
        log.info("{}", config);
    }

    /**
     * websocket 关闭连接时
     */
    @OnClose
    public void onClose(Session session) {
        int onlineUserCount = onlineCount.addAndGet(-1);
        log.info("当前在线用户 ： {}", onlineUserCount);
        log.info("{}", session);
        log.info("onClose");
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.info("{}", session);
        log.info("onError");
        log.error(error.getMessage());
    }

    /**
     * websocket传输信息时
     */
    @OnMessage
    public void onMessage(Session session, String message) {
        Message userMessage = JSONObject.parseObject(message, Message.class);
        log.info("{}", userMessage);
        log.info("{}", session);
        log.info("onMessage");
        onLineUsers.get(userMessage.getUserId()).getAsyncRemote().sendText(userMessage.getContent());
        log.info(String.valueOf(new Date().getTime()));
    }
}
